home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Games / Doom / ADoom-0.8 / ADoom_src / amiga_draw.s < prev    next >
Text File  |  1998-06-24  |  37KB  |  1,605 lines

  1. *
  2. *       amiga_draw.s - optimized rendering
  3. *       by Aki Laukkanen <amlaukka@cc.helsinki.fi>
  4. *
  5. *       This file is public domain.
  6. *
  7.  
  8. ;        mc68020
  9. ;        multipass
  10. ;    if (_eval(DEBUG)&$8000)
  11. ;        debug    on,lattice4
  12. ;    endc
  13.  
  14.         include "exec/types.i"
  15.  
  16. ;-----------------------------------------------------------------------
  17.  
  18. SCREENWIDTH    equ    320
  19.  
  20. FUZZTABLE    equ    250
  21. FUZZOFF        equ    SCREENWIDTH
  22.  
  23. FRACBITS    equ    16
  24. FRACUNIT    equ    (1<<FRACBITS)
  25.  
  26. *
  27. *       global functions
  28. *
  29.  
  30. ;;        xdef    _R_DrawColumn_030            ; high detail
  31. ;;        xdef    @R_DrawColumn_030
  32.         xdef    _R_DrawColumn_040            ; high detail
  33.         xdef    @R_DrawColumn_040
  34.         xdef    _R_DrawSpan_040
  35.         xdef    @R_DrawSpan_040
  36.         xdef    _R_DrawColumn_060
  37.         xdef    @R_DrawColumn_060
  38.         xdef    _R_DrawSpan_060
  39.         xdef    @R_DrawSpan_060
  40.         xdef    _R_DrawFuzzColumn
  41.         xdef    @R_DrawFuzzColumn
  42. ;;        xdef    _R_DrawTranslatedColumn
  43. ;;        xdef    @R_DrawTranslatedColumn
  44.  
  45.         xdef    _R_DrawSpanLow                ; low detail
  46.         xdef    @R_DrawSpanLow
  47.         xdef    _R_DrawColumnLow
  48.         xdef    @R_DrawColumnLow
  49.         xdef    _R_DrawFuzzColumnLow
  50.         xdef    @R_DrawFuzzColumnLow
  51. ;;        xdef    _R_DrawTranslatedColumnLow
  52. ;;        xdef    @R_DrawTranslatedColumnLow
  53.         
  54.         xdef    _R_RenderSegLoop
  55.         xdef    @R_RenderSegLoop
  56.  
  57. *
  58. *       needed symbols/labels
  59. *
  60.  
  61.         xref    _dc_yl
  62.         xref    _dc_yh
  63.         xref    _dc_x
  64.         xref    _columnofs
  65.         xref    _ylookup
  66.         xref    _dc_iscale
  67.         xref    _centery
  68.         xref    _dc_texturemid
  69.         xref    _dc_source
  70.         xref    _dc_colormap
  71.         xref    _ds_xfrac
  72.         xref    _ds_yfrac
  73.         xref    _ds_x1
  74.         xref    _ds_y
  75.         xref    _ds_x2
  76.         xref    _ds_xstep
  77.         xref    _ds_ystep
  78.         xref    _ds_source
  79.         xref    _ds_colormap
  80.         xref    _fuzzoffset
  81.         xref    _fuzzpos
  82.         xref    _viewheight
  83.         xref    _dc_translation
  84.         xref    _colormaps
  85.  
  86. ;-----------------------------------------------------------------------
  87.         section    text,code
  88.  
  89. ; low detail drawing functions
  90.  
  91. ;-----------------------------------------------------------------------
  92.         cnop    0,4
  93.  
  94. _R_DrawColumnLow
  95. @R_DrawColumnLow
  96.         movem.l d3-d4/d6-d7/a2/a3,-(sp)
  97.  
  98.         move.l  _dc_yh(a4),d7    ; count = _dc_yh - _dc_yl
  99.         move.l  _dc_yl(a4),d0
  100.         sub.l   d0,d7
  101.         bmi.w   .end1
  102.  
  103.         move.l  _dc_x(a4),d1    ; dest = ylookup[_dc_yl] + columnofs[_dc_x]
  104.         lea     _ylookup(a4),a0
  105.         add.l    d1,d1        ; dc_x <<= 1 
  106.         move.l  (a0,d0.l*4),a0
  107.         lea     _columnofs(a4),a1
  108.         add.l   (a1,d1.l*4),a0
  109.  
  110.         move.l  _dc_colormap(a4),d4
  111.         move.l  _dc_source(a4),a1
  112.  
  113.         move.l  _dc_iscale(a4),d1 ; frac = _dc_texturemid + (_dc_yl-centery)*fracstep
  114.         sub.l   _centery(a4),d0
  115.         muls.l  d1,d0
  116.         add.l   _dc_texturemid(a4),d0
  117.  
  118.         moveq   #$7f,d3
  119.         lea     (SCREENWIDTH*4).w,a3
  120.  
  121. ; d7: cnt >> 2
  122. ; a0: chunky
  123. ; a1: texture
  124. ; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
  125. ; d1: dfrac (.......................................)
  126. ; d3: $7f
  127. ; d4: light table aligned to 256 byte boundary
  128. ; a3: SCREENWIDTH
  129.  
  130.         move.l  d7,d6
  131.         and.w   #3,d6
  132.  
  133.         swap    d0              ; swap decimals and fraction
  134.         swap    d1
  135.  
  136.         add.w   .width_tab1(pc,d6.w*2),a0
  137.         lsr.w   #2,d7
  138.         move.w  .tmap_tab1(pc,d6.w*2),d6
  139.  
  140.         and.w   d3,d0
  141.         sub.w   d1,d0
  142.         add.l   d1,d0           ; setup the X flag
  143.  
  144.         jmp     .loop1(pc,d6.w)
  145.  
  146.         cnop    0,4
  147. .width_tab1
  148.         dc.w    -3*SCREENWIDTH
  149.         dc.w    -2*SCREENWIDTH
  150.         dc.w    -1*SCREENWIDTH
  151.         dc.w    0
  152. .tmap_tab1
  153.         dc.w    .01-.loop1
  154.         dc.w    .11-.loop1
  155.         dc.w    .21-.loop1
  156.         dc.w    .31-.loop1
  157. .loop1
  158. .31
  159.         move.b  (a1,d0.w),d4
  160.         addx.l  d1,d0
  161.         move.l  d4,a2
  162.         move.w  (a2),d6
  163.         and.w   d3,d0
  164.         move.b    (a2),d6
  165.         move.w    d6,(a0)
  166. .21
  167.         move.b  (a1,d0.w),d4
  168.         addx.l  d1,d0
  169.         move.l  d4,a2
  170.         move.w  (a2),d6
  171.         and.w   d3,d0
  172.         move.b    (a2),d6
  173.         move.w    d6,SCREENWIDTH(a0)
  174. .11
  175.         move.b  (a1,d0.w),d4
  176.         addx.l  d1,d0
  177.         move.l  d4,a2
  178.         move.w  (a2),d6
  179.         and.w   d3,d0
  180.         move.b    (a2),d6
  181.         move.w    d6,SCREENWIDTH*2(a0)
  182. .01
  183.         move.b  (a1,d0.w),d4
  184.         addx.l  d1,d0
  185.         move.l  d4,a2
  186.         move.w    (a2),d6
  187.         and.w   d3,d0
  188.         move.b  (a2),d6
  189.         move.w    d6,SCREENWIDTH*3(a0)
  190.  
  191.         add.l   a3,a0
  192. .loop_end1
  193.         dbf     d7,.loop1
  194. .end1
  195.         movem.l (sp)+,d3-d4/d6-d7/a2/a3
  196.         rts
  197.  
  198. ;-----------------------------------------------------------------------
  199.         cnop    0,4
  200.  
  201. _R_DrawSpanLow
  202. @R_DrawSpanLow
  203.         movem.l d2-d7/a2-a4,-(sp)
  204.         move.l  _ds_y(a4),d0
  205.         move.l  _ds_x1(a4),d1    ; dest = ylookup[_ds_y] + columnofs[_ds_x1]
  206.         lea     _ylookup(a4),a0
  207.         add.l    d1,d1
  208.         move.l  (a0,d0.l*4),a0
  209.         lea     _columnofs(a4),a1
  210.         add.l   (a1,d1.l*4),a0
  211.         move.l  _ds_x2(a4),d7    ; count = _ds_x2 - _ds_x1
  212.         move.l  _ds_source(a4),a1
  213.         add.l    d7,d7
  214.         move.l  _ds_colormap(a4),a2
  215.         sub.l   d1,d7
  216.         addq.l    #2,d7
  217.         move.l  _ds_xfrac(a4),d0
  218.         move.l  _ds_yfrac(a4),d1
  219.         move.l  _ds_xstep(a4),d2
  220.         move.l  _ds_ystep(a4),d3
  221.         move.l  a0,d4        ; notice, that this address must already be aligned by word
  222.         btst    #1,d4
  223.         beq.b   .skips2
  224.         move.l  d0,d5           ; do the unaligned pixels
  225.         move.l  d1,d6           ; so we can write to longword
  226.         swap    d5              ; boundary in the main loop
  227.         swap    d6
  228.         and.w   #$3f,d5
  229.         and.w   #$3f,d6        ; this is the worst possible
  230.         lsl.w   #6,d6        ; way but hey, this is not a loop
  231.         or.w    d5,d6
  232.         move.b  (a1,d6.w),d5
  233.         add.l   d2,d0
  234.         move.b  (a2,d5.w),(a0)+
  235.         add.l   d3,d1
  236.         move.b    (a2,d5.w),(a0)+    ; I know this is crap but spare me the comments
  237.         subq.l  #2,d7
  238. .skips2        move.l  a2,d4
  239.         lea     $1000(a1),a1    ; catch 22
  240.         move.l  a0,a3
  241.         add.l   d7,a3
  242.         move.l  d7,d5
  243.         and.b   #~7,d5
  244.         move.l  a0,a4
  245.         add.l   d5,a4
  246.         eor.w   d0,d1           ; swap fraction parts for addx
  247.         eor.w   d2,d3
  248.         eor.w   d1,d0
  249.         eor.w   d3,d2
  250.         eor.w   d0,d1
  251.         eor.w   d2,d3
  252.         swap    d0
  253.         swap    d1
  254.         swap    d2
  255.         swap    d3
  256.         lsl.w   #6,d1
  257.         lsl.w   #6,d3
  258.         move.w  #$ffc0,d6
  259.         move.w  #$f03f,d7
  260.         lsr.w   #3,d5
  261.         beq.b   .skip_loop22
  262.         sub.w   d2,d0
  263.         add.l   d2,d0           ; setup the X flag
  264. .loop22        or.w    d6,d0        ; Not really and exercise in optimizing
  265.         or.w    d7,d1        ; but I guess it's faster than 1x1 for 030
  266.         and.w   d1,d0        ; where this low detail business is needed.
  267.         addx.l  d3,d1
  268.         move.b  (a1,d0.w),d4
  269.         addx.l  d2,d0
  270.         move.l  d4,a2
  271.         move.w  (a2),d5
  272.         or.w    d6,d0
  273.         move.b    (a2),d5
  274.         or.w    d7,d1
  275.         and.w   d1,d0
  276.         swap    d5
  277.         addx.l  d3,d1
  278.         move.b  (a1,d0.w),d4
  279.         addx.l  d2,d0
  280.         move.l  d4,a2
  281.         move.w  (a2),d5
  282.         or.w    d6,d0
  283.         move.b    (a2),d5
  284.         or.w    d7,d1
  285.         and.w   d1,d0
  286.         move.l    d5,(a0)+
  287.         addx.l  d3,d1
  288.         move.b  (a1,d0.w),d4
  289.         addx.l  d2,d0
  290.         move.l  d4,a2
  291.         move.w  (a2),d5
  292.         or.w    d6,d0
  293.         move.b    (a2),d5
  294.         or.w    d7,d1
  295.         and.w   d1,d0
  296.         swap    d5
  297.         addx.l  d3,d1
  298.         move.b  (a1,d0.w),d4
  299.         addx.l  d2,d0
  300.         move.l  d4,a2
  301.         move.w  (a2),d5
  302.         move.b    (a2),d5
  303.         move.l  d5,(a0)+
  304.         cmp.l   a0,a4
  305.         bne.b   .loop22
  306. .skip_loop22
  307.         sub.w   d2,d0
  308.         add.l   d2,d0
  309.  
  310.         bra.b   .loop_end22
  311. .loop32      or.w    d6,d0
  312.         or.w    d7,d1
  313.         and.w   d1,d0
  314.         addx.l  d3,d1
  315.         move.b  (a1,d0.w),d4
  316.         addx.l  d2,d0
  317.         move.l  d4,a2
  318.         move.b  (a2),(a0)+
  319.         move.b    (a2),(a0)+
  320. .loop_end22
  321.         cmp.l   a0,a3
  322.         bne.b   .loop32
  323. .end22        movem.l (sp)+,d2-d7/a2-a4
  324.         rts
  325.  
  326. ;-----------------------------------------------------------------------
  327.         cnop    0,4
  328.  
  329. _R_DrawTranslatedColumnLow
  330. @R_DrawTranslatedColumnLow
  331.         movem.l d2-d4/d6-d7/a2/a3,-(sp)
  332.  
  333.         move.l  _dc_yh(a4),d7    ; count = _dc_yh - _dc_yl
  334.         move.l  _dc_yl(a4),d0
  335.         sub.l   d0,d7
  336.         bmi.w   .end3
  337.  
  338.         move.l  _dc_x(a4),d1    ; dest = ylookup[_dc_yl] + columnofs[_dc_x]
  339.         lea     _ylookup(a4),a0
  340.         add.l    d1,d1
  341.         move.l  (a0,d0.l*4),a0
  342.         lea     _columnofs(a4),a1
  343.         add.l   (a1,d1.l*4),a0
  344.  
  345.         move.l    _dc_translation(a4),d2
  346.         move.l  _dc_colormap(a4),d4
  347.         move.l  _dc_source(a4),a1
  348.  
  349.         move.l  _dc_iscale(a4),d1 ; frac = _dc_texturemid + (_dc_yl-centery)*fracstep
  350.         sub.l   _centery(a4),d0
  351.         muls.l  d1,d0
  352.         add.l   _dc_texturemid(a4),d0
  353.  
  354.         moveq   #$7f,d3
  355.         lea     (SCREENWIDTH*4).w,a3
  356.  
  357. ; d7: cnt >> 2
  358. ; a0: chunky
  359. ; a1: texture
  360. ; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
  361. ; d1: dfrac (.......................................)
  362. ; d3: $7f
  363. ; d4: light table aligned to 256 byte boundary
  364. ; d2: translation table aligned to 256 byte boundary
  365. ; a3: SCREENWIDTH
  366.  
  367.         move.l  d7,d6
  368.         and.w   #3,d6
  369.  
  370.         swap    d0              ; swap decimals and fraction
  371.         swap    d1
  372.  
  373.         add.w   .width_tab3(pc,d6.w*2),a0
  374.         lsr.w   #2,d7
  375.         move.w  .tmap_tab3(pc,d6.w*2),d6
  376.  
  377.         and.w   d3,d0
  378.         sub.w   d1,d0
  379.         add.l   d1,d0           ; setup the X flag
  380.  
  381.         jmp     .loop3(pc,d6.w)
  382.  
  383.         cnop    0,4
  384. .width_tab3
  385.         dc.w    -3*SCREENWIDTH
  386.         dc.w    -2*SCREENWIDTH
  387.         dc.w    -1*SCREENWIDTH
  388.         dc.w    0
  389. .tmap_tab3
  390.         dc.w    .03-.loop3
  391.         dc.w    .13-.loop3
  392.         dc.w    .23-.loop3
  393.         dc.w    .33-.loop3
  394. .loop3
  395. .33
  396.         move.b  (a1,d0.w),d2
  397.         move.l    d2,a2
  398.         addx.l  d1,d0
  399.         move.b    (a2),d4
  400.         move.l  d4,a2
  401.         and.w   d3,d0
  402.         move.w    (a2),d6
  403.         move.b  (a2),d6
  404.         move.w    d6,(a0)
  405. .23
  406.         move.b  (a1,d0.w),d2
  407.         move.l    d2,a2
  408.         addx.l  d1,d0
  409.         move.b    (a2),d4
  410.         move.l  d4,a2
  411.         and.w   d3,d0
  412.         move.w    (a2),d6
  413.         move.b  (a2),d6
  414.         move.w    d6,SCREENWIDTH(a0)
  415. .13
  416.         move.b  (a1,d0.w),d2
  417.         move.l    d2,a2
  418.         addx.l  d1,d0
  419.         move.b    (a2),d4
  420.         move.l  d4,a2
  421.         and.w   d3,d0
  422.         move.w    (a2),d6
  423.         move.b    (a2),d6
  424.         move.w  d6,SCREENWIDTH*2(a0)
  425. .03
  426.         move.b  (a1,d0.w),d2
  427.         move.l    d2,a2
  428.         addx.l  d1,d0
  429.         move.b    (a2),d4
  430.         move.l  d4,a2
  431.         and.w   d3,d0
  432.         move.w    (a2),d6
  433.         move.b    (a2),d6
  434.         move.b  d6,SCREENWIDTH*3(a0)
  435.  
  436.         add.l   a3,a0
  437. .loop_end3
  438.         dbf     d7,.loop3
  439. .end3
  440.         movem.l (sp)+,d2-d4/d6-d7/a2/a3
  441.         rts
  442.  
  443. ;-----------------------------------------------------------------------
  444.         cnop    0,4
  445.  
  446. _R_DrawFuzzColumnLow
  447. @R_DrawFuzzColumnLow
  448.         movem.l d4/d6-d7/a2/a3,-(sp)
  449.  
  450.         move.l    _viewheight(a4),d1
  451.         subq.l    #1,d1
  452.         move.l  _dc_yh(a4),d7    ; count = _dc_yh - _dc_yl
  453.         cmp.l    d1,d7
  454.         bne.b    .skip_yh4
  455.         subq.l    #1,d1
  456.         move.l    d1,d7
  457. .skip_yh4
  458.         move.l  _dc_yl(a4),d0
  459.         bne.b    .skip_yl4
  460.         moveq    #1,d0
  461. .skip_yl4
  462.         sub.l   d0,d7
  463.         bmi.w   .end4
  464.  
  465.         move.l  _dc_x(a4),d1    ; dest = ylookup[_dc_yl] + columnofs[_dc_x]
  466.         lea     _ylookup(a4),a0
  467.         add.l    d1,d1
  468.         move.l  (a0,d0.l*4),a0
  469.         lea     _columnofs(a4),a1
  470.         add.l   (a1,d1.l*4),a0
  471.  
  472.         move.l  _colormaps(a4),d4
  473.         add.l    #6*256,d4
  474.  
  475.         lea    _fuzzoffset(a4),a1
  476.         move.l    _fuzzpos(a4),d0    ; bring it down 
  477. .pos_loop4    sub.w    #200,d0
  478.         bpl    .pos_loop4
  479.         add.w    #200,d0
  480.         add.l    d0,a1
  481.  
  482.         lea     (SCREENWIDTH*4).w,a3
  483.  
  484. ; d7: cnt >> 2
  485. ; a0: chunky
  486. ; a1: fuzzoffset
  487. ; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
  488. ; d1: dfrac (.......................................)
  489. ; d3: $7f
  490. ; d4: light table aligned to 256 byte boundary
  491. ; a3: SCREENWIDTH
  492.  
  493.         move.l  d7,d6
  494.         and.w   #3,d6
  495.  
  496.         add.w   .width_tab4(pc,d6.w*2),a0
  497.         lsr.w   #2,d7
  498.         move.w  .tmap_tab4(pc,d6.w*2),d6
  499.  
  500.         jmp     .loop4(pc,d6.w)
  501.  
  502.         cnop    0,4
  503. .width_tab4
  504.         dc.w    -3*SCREENWIDTH
  505.         dc.w    -2*SCREENWIDTH
  506.         dc.w    -1*SCREENWIDTH
  507.         dc.w    0
  508. .tmap_tab4
  509.         dc.w    .04-.loop4
  510.         dc.w    .14-.loop4
  511.         dc.w    .24-.loop4
  512.         dc.w    .34-.loop4
  513. .loop4
  514. .34        move.l    a0,a2            ; This is essentially
  515.         add.l    (a1)+,a2        ; just moving memory around.
  516.         move.b    (a2),d4
  517.         move.l    d4,a2            
  518.         move.w    (a2),d6
  519.         move.b    (a2),d6
  520.         move.w    d6,(a0)        
  521. .24        lea    SCREENWIDTH(a0),a2    
  522.         add.l    (a1)+,a2        
  523.         move.b    (a2),d4            
  524.         move.l    d4,a2
  525.         move.w    (a2),d6
  526.         move.b    (a2),d6
  527.         move.w    d6,SCREENWIDTH(a0)
  528. .14        lea    2*SCREENWIDTH(a0),a2
  529.         add.l    (a1)+,a2
  530.         move.b    (a2),d4
  531.         move.l    d4,a2
  532.         move.w    (a2),d6
  533.         move.b    (a2),d6
  534.         move.w    d6,2*SCREENWIDTH(a0)
  535. .04        lea    3*SCREENWIDTH(a0),a2
  536.         add.l    (a1)+,a2
  537.         move.b    (a2),d4
  538.         move.l    d4,a2
  539.         move.w    (a2),d6
  540.         move.b    (a2),d6
  541.         move.w    d6,3*SCREENWIDTH(a0)
  542.  
  543.         add.l   a3,a0
  544. .loop_end4
  545.         dbf    d7,.loop4
  546.         sub.l    #_fuzzoffset,a1
  547.         move.l    a1,_fuzzpos
  548. .end4
  549.         movem.l (sp)+,d4/d6-d7/a2/a3
  550.         rts
  551.  
  552. ;-----------------------------------------------------------------------
  553. ; high detail versions
  554.  
  555. ;-----------------------------------------------------------------------
  556.         cnop    0,4
  557.  
  558. _R_DrawFuzzColumn
  559. @R_DrawFuzzColumn
  560.         movem.l d4/d6-d7/a2/a3,-(sp)
  561.  
  562.         move.l    _viewheight(a4),d1
  563.         subq.l    #1,d1
  564.         move.l  _dc_yh(a4),d7    ; count = _dc_yh - _dc_yl
  565.         cmp.l    d1,d7
  566.         bne.b    .skip_yh5
  567.         subq.l    #1,d1
  568.         move.l    d1,d7
  569. .skip_yh5
  570.         move.l  _dc_yl(a4),d0
  571.         bne.b    .skip_yl5
  572.         moveq    #1,d0
  573. .skip_yl5
  574.         sub.l   d0,d7
  575.         bmi.w   .end5
  576.  
  577.         move.l  _dc_x(a4),d1    ; dest = ylookup[_dc_yl] + columnofs[_dc_x]
  578.         lea     _ylookup(a4),a0
  579.         move.l  (a0,d0.l*4),a0
  580.         lea     _columnofs(a4),a1
  581.         add.l   (a1,d1.l*4),a0
  582.  
  583.         move.l  _colormaps(a4),d4
  584.         add.l    #6*256,d4
  585.  
  586.         lea    _fuzzoffset(a4),a1
  587.         move.l    _fuzzpos(a4),d0
  588. .pos_loop5    sub.w    #200,d0
  589.         bpl    .pos_loop5
  590.         add.w    #200,d0
  591.         add.l    d0,a1
  592.  
  593.         lea     (SCREENWIDTH*4).w,a3
  594.  
  595. ; d7: cnt >> 2
  596. ; a0: chunky
  597. ; a1: fuzzoffset
  598. ; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
  599. ; d1: dfrac (.......................................)
  600. ; d3: $7f
  601. ; d4: light table aligned to 256 byte boundary
  602. ; a3: SCREENWIDTH
  603.  
  604.         move.l  d7,d6
  605.         and.w   #3,d6
  606.  
  607.         add.w   .width_tab5(pc,d6.w*2),a0
  608.         lsr.w   #2,d7
  609.         move.w  .tmap_tab5(pc,d6.w*2),d6
  610.  
  611.         jmp     .loop5(pc,d6.w)
  612.  
  613.         cnop    0,4
  614. .width_tab5
  615.         dc.w    -3*SCREENWIDTH
  616.         dc.w    -2*SCREENWIDTH
  617.         dc.w    -1*SCREENWIDTH
  618.         dc.w    0
  619. .tmap_tab5
  620.         dc.w    .05-.loop5
  621.         dc.w    .15-.loop5
  622.         dc.w    .25-.loop5
  623.         dc.w    .35-.loop5
  624. .loop5
  625. .35        move.l    a0,a2            ; This is essentially
  626.         add.l    (a1)+,a2        ; just moving memory around.
  627.         move.b    (a2),d4
  628.         move.l    d4,a2            ; Not 060 optimized but
  629.         move.b    (a2),(a0)        ; if you have hordes of
  630. .25        lea    SCREENWIDTH(a0),a2    ; invisible monsters which
  631.         add.l    (a1)+,a2        ; slow down the game too much,
  632.         move.b    (a2),d4            ; do tell me.
  633.         move.l    d4,a2
  634.         move.b    (a2),SCREENWIDTH(a0)
  635. .15        lea    2*SCREENWIDTH(a0),a2
  636.         add.l    (a1)+,a2
  637.         move.b    (a2),d4
  638.         move.l    d4,a2
  639.         move.b    (a2),2*SCREENWIDTH(a0)
  640. .05        lea    3*SCREENWIDTH(a0),a2
  641.         add.l    (a1)+,a2
  642.         move.b    (a2),d4
  643.         move.l    d4,a2
  644.         move.b    (a2),3*SCREENWIDTH(a0)
  645.  
  646.         add.l   a3,a0
  647. .loop_end5
  648.         dbf    d7,.loop5
  649.         sub.l    #_fuzzoffset,a1
  650.         move.l    a1,_fuzzpos
  651. .end5
  652.         movem.l (sp)+,d4/d6-d7/a2/a3
  653.         rts
  654.  
  655. ;-----------------------------------------------------------------------
  656.         cnop    0,4
  657.  
  658. _R_DrawTranslatedColumn                    ; no 060 version :(
  659. @R_DrawTranslatedColumn
  660.         movem.l d2-d4/d6-d7/a2/a3,-(sp)
  661.  
  662.         move.l  _dc_yh(a4),d7    ; count = _dc_yh - _dc_yl
  663.         move.l  _dc_yl(a4),d0
  664.         sub.l   d0,d7
  665.         bmi.w   .end6
  666.  
  667.         move.l  _dc_x(a4),d1    ; dest = ylookup[_dc_yl] + columnofs[_dc_x]
  668.         lea     _ylookup(a4),a0
  669.         move.l  (a0,d0.l*4),a0
  670.         lea     _columnofs(a4),a1
  671.         add.l   (a1,d1.l*4),a0
  672.  
  673.         move.l    _dc_translation(a4),d2
  674.         move.l  _dc_colormap(a4),d4
  675.         move.l  _dc_source(a4),a1
  676.  
  677.         move.l  _dc_iscale(a4),d1 ; frac = _dc_texturemid + (_dc_yl-centery)*fracstep
  678.         sub.l   _centery(a4),d0
  679.         muls.l  d1,d0
  680.         add.l   _dc_texturemid(a4),d0
  681.  
  682.         moveq   #$7f,d3
  683.         lea     (SCREENWIDTH*4).w,a3
  684.  
  685. ; d7: cnt >> 2
  686. ; a0: chunky
  687. ; a1: texture
  688. ; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
  689. ; d1: dfrac (.......................................)
  690. ; d3: $7f
  691. ; d4: light table aligned to 256 byte boundary
  692. ; d2: translation table aligned to 256 byte boundary
  693. ; a3: SCREENWIDTH
  694.  
  695.         move.l  d7,d6
  696.         and.w   #3,d6
  697.  
  698.         swap    d0              ; swap decimals and fraction
  699.         swap    d1
  700.  
  701.         add.w   .width_tab6(pc,d6.w*2),a0
  702.         lsr.w   #2,d7
  703.         move.w  .tmap_tab6(pc,d6.w*2),d6
  704.  
  705.         and.w   d3,d0
  706.         sub.w   d1,d0
  707.         add.l   d1,d0           ; setup the X flag
  708.  
  709.         jmp     .loop6(pc,d6.w)
  710.  
  711.         cnop    0,4
  712. .width_tab6
  713.         dc.w    -3*SCREENWIDTH
  714.         dc.w    -2*SCREENWIDTH
  715.         dc.w    -1*SCREENWIDTH
  716.         dc.w    0
  717. .tmap_tab6
  718.         dc.w    .06-.loop6
  719.         dc.w    .16-.loop6
  720.         dc.w    .26-.loop6
  721.         dc.w    .36-.loop6
  722. .loop6
  723. .36
  724.         move.b  (a1,d0.w),d2
  725.         move.l    d2,a2
  726.         addx.l  d1,d0
  727.         move.b    (a2),d4
  728.         and.w   d3,d0
  729.         move.l  d4,a2
  730.         move.b  (a2),(a0)
  731. .26
  732.         move.b  (a1,d0.w),d2
  733.         move.l    d2,a2
  734.         addx.l  d1,d0
  735.         move.b    (a2),d4
  736.         and.w   d3,d0
  737.         move.l  d4,a2
  738.         move.b  (a2),SCREENWIDTH(a0)
  739. .16
  740.         move.b  (a1,d0.w),d2
  741.         move.l    d2,a2
  742.         addx.l  d1,d0
  743.         move.b    (a2),d4
  744.         and.w   d3,d0
  745.         move.l  d4,a2
  746.         move.b  (a2),SCREENWIDTH*2(a0)
  747. .06
  748.         move.b  (a1,d0.w),d2
  749.         move.l    d2,a2
  750.         addx.l  d1,d0
  751.         move.b    (a2),d4
  752.         and.w   d3,d0
  753.         move.l  d4,a2
  754.         move.b  (a2),SCREENWIDTH*3(a0)
  755.  
  756.         add.l   a3,a0
  757. .loop_end6
  758.         dbf     d7,.loop6
  759. .end6
  760.         movem.l (sp)+,d2-d4/d6-d7/a2/a3
  761.         rts
  762.  
  763. ;-----------------------------------------------------------------------
  764.         cnop    0,4
  765.  
  766. ; routine from j.selck@flensburg.netsurf.de   (Aki's 040 routine is faster)
  767.  
  768. ;_R_DrawColumn_030
  769. ;@R_DrawColumn_030
  770. ;        movem.l    d3-d7/a2-a5,-(sp)
  771. ;        move.l    _dc_yl(a4),d0
  772. ;        move.l    _dc_yh(a4),d7
  773. ;        sub.l    d0,d7
  774. ;        bmi.b    1$
  775. ;        move.l    _dc_x(a4),d1
  776. ;        lea    _columnofs(a4),a5
  777. ;        lea    (a5,d1.l*4),a1
  778. ;        lea    _ylookup(a4),a5
  779. ;        movea.l    (a5,d0.l*4),a2
  780. ;        adda.l    (a1),a2
  781. ;        move.l    _dc_iscale(a4),d6
  782. ;        sub.l    _centery(a4),d0
  783. ;        muls.l    d6,d0
  784. ;        move.l    _dc_texturemid(a4),d5
  785. ;        add.l    d0,d5
  786. ;        movea.l    _dc_source(a4),a3
  787. ;        movea.l    _dc_colormap(a4),a4
  788. ;        moveq    #127,d4
  789. ;        move.l    #SCREENWIDTH,d3
  790. ;        moveq    #0,d1        ; ensure high bits of d1 are clear
  791. ;        add.w    d6,d5        ; frac += fracstep (also sets X flag)
  792. ;        swap    d5        ; swap(frac)
  793. ;        swap    d6        ; swap(fracstep)
  794. ;        and.w    d4,d5        ; (frac>>16)&127
  795. ;2$        move.b    (a3,d5.w),d1    ; dc_source[(frac>>FRACBITS)&127]
  796. ;        move.b    (a4,d1.w),(a2)    ; *dest = dc_colormap[d1]
  797. ;        addx.l    d6,d5        ; swap(frac += fracstep), use & set X
  798. ;        adda.l    d3,a2        ; dest += SCREENWIDTH
  799. ;        and.w    d4,d5        ; (frac>>16)&127
  800. ;        dbra    d7,2$
  801. ;1$        movem.l    (sp)+,d3-d7/a2-a5
  802. ;        rts
  803.  
  804. ;-----------------------------------------------------------------------
  805.         cnop    0,4
  806.  
  807. _R_DrawColumn_060
  808. @R_DrawColumn_060
  809.         movem.l d2-d3/d5-d7/a2/a3,-(sp)
  810.  
  811.         move.l  (_dc_yh),d7     ; count = _dc_yh - _dc_yl
  812.         move.l  (_dc_yl),d0
  813.         sub.l   d0,d7
  814.         bmi.w   .end7
  815.  
  816.         move.l  (_dc_x),d1      ; dest = ylookup[_dc_yl] + columnofs[_dc_x]
  817.         lea     (_ylookup),a0
  818.         move.l  (a0,d0.l*4),a0
  819.         lea     (_columnofs),a1
  820.         add.l   (a1,d1.l*4),a0
  821.  
  822.         move.l  (_dc_colormap),a2
  823.         move.l  (_dc_source),a1
  824.  
  825.         move.l  (_dc_iscale),d1 ; frac = _dc_texturemid + (_dc_yl-centery)*fracstep
  826.         sub.l   (_centery),d0
  827.         muls.l  d1,d0
  828.         add.l   (_dc_texturemid),d0
  829.  
  830.         moveq   #$7f,d3
  831.         move.l  #SCREENWIDTH,a3
  832.  
  833.         move.l  d7,d6           ; Do the leftover iterations in
  834.         and.w   #3,d6           ; this loop.
  835.         addq.w    #1,d6
  836. .skip_loop7
  837.         move.l  d0,d5
  838.         swap    d5
  839.         and.l   d3,d5
  840.         move.b  (a1,d5.w),d5
  841.         add.l   d1,d0
  842.         move.b  (a2,d5.w),(a0)
  843.         add.l   a3,a0
  844.         subq.w  #1,d6
  845.         bne.b   .skip_loop7
  846. ; d7: cnt >> 2
  847. ; a0: chunky
  848. ; a1: texture
  849. ; a2: light_table
  850. ; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
  851. ; d1: dfrac*2   (.......................................)
  852. ; d2: frac+dfrac(.......................................)
  853. ; d3: $7f
  854. ; a3: SCREENWIDTH
  855. .skip7
  856.         lsr.l   #2,d7
  857.         subq.l    #1,d7
  858.         bmi.b    .end7
  859.  
  860.         add.l   a3,a3
  861.  
  862.         move.l  d0,d2
  863.         add.l   a3,a3
  864.         add.l   d1,d2
  865.         add.l   d1,d1
  866.  
  867.         eor.w   d0,d2           ; swap the fraction part for addx
  868.         eor.w   d2,d0           ; assuming 16.16 fixed point
  869.         eor.w   d0,d2
  870.  
  871.         swap    d0              ; swap decimals and fraction
  872.         swap    d1
  873.         swap    d2
  874.  
  875.         moveq   #0,d5
  876.         and.w   d3,d2
  877.         and.w   d3,d0
  878.  
  879.         sub.w   d1,d0
  880.         add.l   d1,d0           ; setup the X flag
  881.  
  882.         move.b  (a1,d2.w),d5
  883. .loop7
  884.         ; This should be reasonably scheduled for
  885.         ; m68060. It should perform well on other processors
  886.         ; too. That AGU stall still bothers me though.
  887.  
  888.         move.b  (a1,d0.w),d6        ; stall + pOEP but allows sOEP
  889.         addx.l  d1,d2               ; pOEP only
  890.         move.b  (a2,d5.l),d5        ; pOEP but allows sOEP
  891.         and.w   d3,d2               ; sOEP
  892.         move.b  (a2,d6.l),d6        ; pOEP but allows sOEP
  893.         move.b  d5,SCREENWIDTH(a0)  ; sOEP
  894.         addx.l  d1,d0               ; pOEP only
  895.         move.b  (a1,d2.w),d5        ; pOEP but allows sOEP
  896.         and.w   d3,d0               ; sOEP
  897.         move.b  d6,(a0)             ; pOEP
  898.                         ; = ~4 cycles/pixel
  899.                         ; + cache misses
  900.  
  901.         ; The vertical writes are the true timehog of the loop
  902.         ; because of the characteristics of the copyback cache
  903.         ; operation.
  904.         
  905.         ; Better mark the chunky buffer as write through
  906.         ; with the MMU and have all the horizontal writes
  907.         ; be longs aligned to longword boundary.
  908.  
  909.         move.b  (a1,d0.w),d6
  910.         addx.l  d1,d2
  911.         move.b  (a2,d5.l),d5
  912.         and.w   d3,d2
  913.         move.b  (a2,d6.l),d6
  914.         move.b  d5,SCREENWIDTH*3(a0)
  915.         addx.l  d1,d0
  916.         move.b  (a1,d2.w),d5
  917.         and.w   d3,d0
  918.         move.b  d6,SCREENWIDTH*2(a0)
  919.  
  920.         add.l   a3,a0
  921. .loop_end7
  922.         dbf     d7,.loop7
  923.  
  924.         ; it's faster to divide it to two lines on 060
  925.         ; and shouldn't be slower on 040.
  926.  
  927. ;        move.b  (a1,d0.w),d6    ; new
  928. ;        move.b  (a2,d6.l),d6    ; new
  929. ;        move.b  d6,(a0)     ; new
  930.  
  931. .end7
  932.         movem.l (sp)+,d2-d3/d5-d7/a2/a3
  933.         rts
  934.  
  935. ;-----------------------------------------------------------------------
  936.         cnop    0,4
  937.  
  938. ; 040 version
  939.  
  940. _R_DrawColumn_040
  941. @R_DrawColumn_040
  942.         movem.l d3-d4/d6-d7/a2/a3,-(sp)
  943.  
  944.         move.l  _dc_yh(a4),d7     ; count = _dc_yh - _dc_yl
  945.         move.l  _dc_yl(a4),d0
  946.         sub.l   d0,d7
  947.         bmi.w   .end8
  948.  
  949.         move.l  _dc_x(a4),d1      ; dest = ylookup[_dc_yl] + columnofs[_dc_x]
  950.         lea     _ylookup(a4),a0
  951.         move.l  (a0,d0.l*4),a0
  952.         lea     _columnofs(a4),a1
  953.         add.l   (a1,d1.l*4),a0
  954.  
  955.         move.l  _dc_colormap(a4),d4
  956.         move.l  _dc_source(a4),a1
  957.  
  958.         move.l  _dc_iscale(a4),d1 ; frac = _dc_texturemid + (_dc_yl-centery)*fracstep
  959.         sub.l   _centery(a4),d0
  960.         muls.l  d1,d0
  961.         add.l   _dc_texturemid(a4),d0
  962.  
  963.         moveq   #$7f,d3
  964.         lea     (SCREENWIDTH*4).w,a3
  965.  
  966. ; d7: cnt >> 2
  967. ; a0: chunky
  968. ; a1: texture
  969. ; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
  970. ; d1: dfrac (.......................................)
  971. ; d3: $7f
  972. ; d4: light table aligned to 256 byte boundary
  973. ; a3: SCREENWIDTH
  974.  
  975.         move.l  d7,d6
  976.         and.w   #3,d6
  977.  
  978.         swap    d0              ; swap decimals and fraction
  979.         swap    d1
  980.  
  981.         add.w   .width_tab8(pc,d6.w*2),a0
  982.         lsr.w   #2,d7
  983.         move.w  .tmap_tab8(pc,d6.w*2),d6
  984.  
  985.         and.w   d3,d0
  986.         sub.w   d1,d0
  987.         add.l   d1,d0           ; setup the X flag
  988.  
  989.         jmp    .loop8(pc,d6.w)
  990.  
  991.         cnop    0,4
  992. .width_tab8
  993.         dc.w    -3*SCREENWIDTH
  994.         dc.w    -2*SCREENWIDTH
  995.         dc.w    -1*SCREENWIDTH
  996.         dc.w    0
  997. .tmap_tab8
  998.         dc.w    .08-.loop8
  999.         dc.w    .18-.loop8
  1000.         dc.w    .28-.loop8
  1001.         dc.w    .38-.loop8
  1002. .loop8
  1003. .38
  1004.         move.b  (a1,d0.w),d4
  1005.         addx.l  d1,d0
  1006.         move.l  d4,a2
  1007.         and.w   d3,d0
  1008.         move.b  (a2),(a0)
  1009. .28
  1010.         move.b  (a1,d0.w),d4
  1011.         addx.l  d1,d0
  1012.         move.l  d4,a2
  1013.         and.w   d3,d0
  1014.         move.b  (a2),SCREENWIDTH(a0)
  1015. .18
  1016.         move.b  (a1,d0.w),d4
  1017.         addx.l  d1,d0
  1018.         move.l  d4,a2
  1019.         and.w   d3,d0
  1020.         move.b  (a2),SCREENWIDTH*2(a0)
  1021. .08
  1022.         move.b  (a1,d0.w),d4
  1023.         addx.l  d1,d0
  1024.         move.l  d4,a2
  1025.         and.w   d3,d0
  1026.         move.b  (a2),SCREENWIDTH*3(a0)
  1027.  
  1028.         add.l   a3,a0
  1029. .loop_end8
  1030.         dbf d7,.loop8
  1031. .end8
  1032.         movem.l (sp)+,d3-d4/d6-d7/a2/a3
  1033.         rts
  1034.  
  1035. ;-----------------------------------------------------------------------
  1036. ; This faster version by Aki M Laukkanen <amlaukka@cc.helsinki.fi>
  1037.  
  1038.         cnop    0,4
  1039.  
  1040. _R_DrawSpan_060
  1041. @R_DrawSpan_060
  1042.         movem.l d2-d7/a2/a3,-(sp)
  1043.         move.l  (_ds_y),d0
  1044.         move.l  (_ds_x1),d1     ; dest = ylookup[_ds_y] + columnofs[_ds_x1]
  1045.         lea     (_ylookup),a0
  1046.         move.l  (a0,d0.l*4),a0
  1047.         lea     (_columnofs),a1
  1048.         add.l   (a1,d1.l*4),a0
  1049.         move.l  (_ds_source),a1
  1050.         move.l  (_ds_colormap),a2
  1051.         move.l  (_ds_x2),d7     ; count = _ds_x2 - _ds_x1
  1052.         sub.l   d1,d7
  1053.         addq.l  #1,d7
  1054.         move.l  (_ds_xfrac),d0
  1055.         move.l  (_ds_yfrac),d1
  1056.         move.l  (_ds_xstep),d2
  1057.         move.l  (_ds_ystep),d3
  1058.         move.l  a0,d4
  1059.         btst    #0,d4
  1060.         beq.b     .skipb9
  1061.         move.l  d0,d5           ; do the unaligned pixels
  1062.         move.l  d1,d6           ; so we can write to longword
  1063.         swap    d5              ; boundary in the main loop
  1064.         swap    d6
  1065.         and.w   #$3f,d5
  1066.         and.w   #$3f,d6
  1067.         lsl.w   #6,d6
  1068.         or.w    d5,d6
  1069.         move.b  (a1,d6.w),d5
  1070.         add.l   d2,d0
  1071.         move.b  (a2,d5.w),(a0)+
  1072.         add.l   d3,d1
  1073.         move.l  a0,d4
  1074.         subq.l  #1,d7
  1075. .skipb9        btst    #1,d4
  1076.         beq.b     .skips9
  1077.         moveq   #2,d4
  1078.         cmp.l   d4,d7
  1079.         bls.b   .skips9
  1080.         move.l  d0,d5           ; write two pixels
  1081.         move.l  d1,d6
  1082.         swap    d5
  1083.         swap    d6
  1084.         and.w   #$3f,d5
  1085.         and.w   #$3f,d6
  1086.         lsl.w   #6,d6
  1087.         or.w    d5,d6
  1088.         move.b  (a1,d6.w),d5
  1089.         move.w  (a2,d5.w),d4
  1090.         add.l   d2,d0
  1091.         add.l   d3,d1
  1092.         move.l  d0,d5
  1093.         move.l  d1,d6
  1094.         swap    d5
  1095.         swap    d6
  1096.         and.w   #$3f,d5
  1097.         and.w   #$3f,d6
  1098.         lsl.w   #6,d6
  1099.         or.w    d5,d6
  1100.         move.b  (a1,d6.w),d5
  1101.         move.b  (a2,d5.w),d4
  1102.         add.l   d2,d0
  1103.         move.w  d4,(a0)+
  1104.         add.l   d3,d1
  1105.         subq.l  #2,d7
  1106. .skips9        move.l  d7,d6           ; setup registers
  1107.         and.w   #3,d6
  1108.         move.l  d6,a3
  1109.         eor.w   d0,d1           ; swap fraction parts for addx
  1110.         eor.w   d2,d3
  1111.         eor.w   d1,d0
  1112.         eor.w   d3,d2
  1113.         eor.w   d0,d1
  1114.         eor.w   d2,d3
  1115.         swap    d0
  1116.         swap    d1
  1117.         swap    d2
  1118.         swap    d3
  1119.         lsl.w   #6,d1
  1120.         lsl.w   #6,d3
  1121.         moveq   #0,d6
  1122.         moveq   #0,d5
  1123.         sub.l   #$f000,a1
  1124.         lsr.l   #2,d7
  1125.         beq.w   .skip_loop29
  1126.         subq.l  #1,d7
  1127.         sub.w   d3,d1
  1128.         add.l   d3,d1           ; setup the X flag
  1129.         or.w    #$ffc0,d0
  1130.         or.w    #$f03f,d1
  1131.         move.w  d0,d6
  1132.         and.w   d1,d6
  1133.         bra.b   .start_loop29
  1134.         cnop    0,8
  1135. .loop29        or.w    #$ffc0,d0       ; pOEP
  1136.         or.w    #$f03f,d1       ; sOEP
  1137.         move.b  (a2,d5.l),d4    ; pOEP but allows sOEP
  1138.         move.w  d0,d6           ; sOEP
  1139.         and.w   d1,d6           ; pOEP
  1140.         move.l  d4,(a0)+        ; sOEP
  1141. .start_loop29
  1142.         addx.l  d2,d0           ; pOEP only
  1143.         addx.l  d3,d1           ; pOEP only
  1144.         move.b  (a1,d6.l),d5    ; pOEP but allows sOEP
  1145.         or.w    #$ffc0,d0       ; sOEP
  1146.         or.w    #$f03f,d1       ; pOEP
  1147.         move.w  d0,d6           ; sOEP
  1148.         move.w  (a2,d5.l),d4    ; pOEP but allows sOEP
  1149.         and.w   d1,d6           ; sOEP
  1150.         addx.l  d2,d0           ; pOEP only
  1151.         addx.l  d3,d1           ; pOEP only
  1152.         move.b  (a1,d6.l),d5    ; pOEP but allows sOEP
  1153.         or.w    #$ffc0,d0       ; sOEP
  1154.         or.w    #$f03f,d1       ; pOEP
  1155.         move.w  d0,d6           ; sOEP
  1156.         move.b  (a2,d5.l),d4    ; pOEP but allows sOEP
  1157.         and.w   d1,d6           ; sOEP
  1158.         addx.l  d2,d0           ; pOEP only
  1159.         addx.l  d3,d1           ; pOEP only
  1160.         move.b  (a1,d6.l),d5    ; pOEP but allows sOEP
  1161.         or.w    #$ffc0,d0       ; sOEP
  1162.         or.w    #$f03f,d1       ; pOEP
  1163.         move.w  d0,d6           ; sOEP
  1164.         swap    d4              ; pOEP only
  1165.         move.w  (a2,d5.l),d4    ; pOEP but allows sOEP
  1166.         and.w   d1,d6           ; sOEP
  1167.         addx.l  d2,d0           ; pOEP only
  1168.         addx.l  d3,d1           ; pOEP only
  1169.         move.b  (a1,d6.l),d5    ; pOEP but allows sOEP
  1170.         dbf     d7,.loop29      ; pOEP only = 7.75 cycles/pixel
  1171.         move.b  (a2,d5.l),d4
  1172.         move.l  d4,(a0)+
  1173. .skip_loop29
  1174.         sub.w   d3,d1
  1175.         add.l   d3,d1
  1176.         move.l  a3,d7
  1177.         bra.b     .loop_end29
  1178. .loop39      or.w    #$ffc0,d0
  1179.         or.w    #$f03f,d1
  1180.         move.w  d0,d6
  1181.         and.w   d1,d6
  1182.         addx.l  d2,d0
  1183.         addx.l  d3,d1
  1184.         move.b  (a1,d6.l),d5
  1185.         move.b  (a2,d5.l),(a0)+
  1186. .loop_end29
  1187.         dbf     d7,.loop39
  1188. .end29       movem.l (sp)+,d2-d7/a2/a3
  1189.         rts
  1190.  
  1191.         cnop    0,4
  1192.  
  1193. ;-----------------------------------------------------------------------
  1194. ; 030/040 version
  1195.  
  1196. _R_DrawSpan_040
  1197. @R_DrawSpan_040
  1198.         movem.l d2-d7/a2-a4,-(sp)
  1199.         move.l  _ds_y(a4),d0
  1200.         move.l  _ds_x1(a4),d1    ; dest = ylookup[_ds_y] + columnofs[_ds_x1]
  1201.         lea     _ylookup(a4),a0
  1202.         move.l  (a0,d0.l*4),a0
  1203.         lea     _columnofs(a4),a1
  1204.         add.l   (a1,d1.l*4),a0
  1205.         move.l  _ds_source(a4),a1
  1206.         move.l  _ds_colormap(a4),a2
  1207.         move.l  _ds_x2(a4),d7    ; count = _ds_x2 - _ds_x1
  1208.         sub.l   d1,d7
  1209.         addq.l  #1,d7
  1210.         move.l  _ds_xfrac(a4),d0
  1211.         move.l  _ds_yfrac(a4),d1
  1212.         move.l  _ds_xstep(a4),d2
  1213.         move.l  _ds_ystep(a4),d3
  1214.         move.l  a0,d4
  1215.         btst    #0,d4
  1216.         beq.b   .skipb0
  1217.         move.l  d0,d5           ; do the unaligned pixels
  1218.         move.l  d1,d6           ; so we can write to longword
  1219.         swap    d5              ; boundary in the main loop
  1220.         swap    d6
  1221.         and.w   #$3f,d5
  1222.         and.w   #$3f,d6
  1223.         lsl.w   #6,d6
  1224.         or.w    d5,d6
  1225.         move.b  (a1,d6.w),d5
  1226.         add.l   d2,d0
  1227.         move.b  (a2,d5.w),(a0)+
  1228.         add.l   d3,d1
  1229.         move.l  a0,d4
  1230.         subq.l  #1,d7
  1231. .skipb0        btst    #1,d4
  1232.         beq.b   .skips0
  1233.         moveq   #2,d4
  1234.         cmp.l   d4,d7
  1235.         bls.b   .skips0
  1236.         move.l  d0,d5           ; write two pixels
  1237.         move.l  d1,d6
  1238.         swap    d5
  1239.         swap    d6
  1240.         and.w   #$3f,d5
  1241.         and.w   #$3f,d6
  1242.         lsl.w   #6,d6
  1243.         or.w    d5,d6
  1244.         move.b  (a1,d6.w),d5
  1245.         move.w  (a2,d5.w),d4
  1246.         add.l   d2,d0
  1247.         add.l   d3,d1
  1248.         move.l  d0,d5
  1249.         move.l  d1,d6
  1250.         swap    d5
  1251.         swap    d6
  1252.         and.w   #$3f,d5
  1253.         and.w   #$3f,d6
  1254.         lsl.w   #6,d6
  1255.         or.w    d5,d6
  1256.         move.b  (a1,d6.w),d5
  1257.         move.b  (a2,d5.w),d4
  1258.         add.l   d2,d0
  1259.         move.w  d4,(a0)+
  1260.         add.l   d3,d1
  1261.         subq.l  #2,d7
  1262. .skips0        move.l  a2,d4
  1263.         add.l   #$1000,a1       ; catch 22
  1264.         move.l  a0,a3
  1265.         add.l   d7,a3
  1266.         move.l  d7,d5
  1267.         and.b   #~3,d5
  1268.         move.l  a0,a4
  1269.         add.l   d5,a4
  1270.         eor.w   d0,d1           ; swap fraction parts for addx
  1271.         eor.w   d2,d3
  1272.         eor.w   d1,d0
  1273.         eor.w   d3,d2
  1274.         eor.w   d0,d1
  1275.         eor.w   d2,d3
  1276.         swap    d0
  1277.         swap    d1
  1278.         swap    d2
  1279.         swap    d3
  1280.         lsl.w   #6,d1
  1281.         lsl.w   #6,d3
  1282.         move.w  #$ffc0,d6
  1283.         move.w  #$f03f,d7
  1284.         lsr.w   #2,d5
  1285.         beq.b   .skip_loop20
  1286.         sub.w   d2,d0
  1287.         add.l   d2,d0           ; setup the X flag
  1288. .loop20        or.w    d6,d0
  1289.         or.w    d7,d1
  1290.         and.w   d1,d0
  1291.         addx.l  d3,d1
  1292.         move.b  (a1,d0.w),d4
  1293.         addx.l  d2,d0
  1294.         move.l  d4,a2
  1295.         move.w  (a2),d5
  1296.         or.w    d6,d0
  1297.         or.w    d7,d1
  1298.         and.w   d1,d0
  1299.         addx.l  d3,d1
  1300.         move.b  (a1,d0.w),d4
  1301.         addx.l  d2,d0
  1302.         move.l  d4,a2
  1303.         move.b  (a2),d5
  1304.         swap    d5
  1305.         or.w    d6,d0
  1306.         or.w    d7,d1
  1307.         and.w   d1,d0
  1308.         addx.l  d3,d1
  1309.         move.b  (a1,d0.w),d4
  1310.         addx.l  d2,d0
  1311.         move.l  d4,a2
  1312.         move.w  (a2),d5
  1313.         or.w    d6,d0
  1314.         or.w    d7,d1
  1315.         and.w   d1,d0
  1316.         addx.l  d3,d1
  1317.         move.b  (a1,d0.w),d4
  1318.         addx.l  d2,d0
  1319.         move.l  d4,a2
  1320.         move.b  (a2),d5
  1321.         move.l  d5,(a0)+
  1322.         cmp.l   a0,a4
  1323.         bne.b   .loop20
  1324. .skip_loop20
  1325.         sub.w   d2,d0
  1326.         add.l   d2,d0
  1327.  
  1328.         bra.b   .loop_end20
  1329. .loop30        or.w    d6,d0
  1330.         or.w    d7,d1
  1331.         and.w   d1,d0
  1332.         addx.l  d3,d1
  1333.         move.b  (a1,d0.w),d4
  1334.         addx.l  d2,d0
  1335.         move.l  d4,a2
  1336.         move.b  (a2),(a0)+
  1337. .loop_end20
  1338.         cmp.l   a0,a3
  1339.         bne.b   .loop30
  1340. .end20        movem.l (sp)+,d2-d7/a2-a4
  1341.         rts
  1342.  
  1343. ;-----------------------------------------------------------------------
  1344.         xref    _segtextured
  1345.         xref    _markfloor
  1346.         xref    _markceiling
  1347.         xref    _maskedtexture
  1348.         xref    _maskedtexturecol
  1349.         xref    _toptexture
  1350.         xref    _bottomtexture
  1351.         xref    _midtexture
  1352.         xref    _rw_x
  1353.         xref    _rw_stopx
  1354.         xref    _rw_centerangle
  1355.         xref    _rw_offset
  1356.         xref    _rw_distance
  1357.         xref    _rw_scale
  1358.         xref    _rw_scalestep
  1359.         xref    _rw_midtexturemid
  1360.         xref    _rw_toptexturemid
  1361.         xref    _rw_bottomtexturemid
  1362.         xref    _pixhigh
  1363.         xref    _pixlow
  1364.         xref    _pixhighstep
  1365.         xref    _pixlowstep
  1366.         xref    _topfrac
  1367.         xref    _topstep
  1368.         xref    _bottomfrac
  1369.         xref    _bottomstep
  1370.         xref    _walllights
  1371.         xref    _ceilingclip
  1372.         xref    _ceilingplane
  1373.         xref    _floorclip
  1374.         xref    _floorplane
  1375.         xref    _xtoviewangle
  1376.         xref    _finetangent
  1377.         xref    _FixedMul
  1378.         xref    _colfunc
  1379.         xref    @R_GetColumn
  1380.  
  1381.         cnop    0,4
  1382.  
  1383. _R_RenderSegLoop
  1384. @R_RenderSegLoop
  1385.         movem.l    d2-d7/a2-a6,-(sp)
  1386.         movea.l    _rw_x(a4),a2    ; a2 = rw_x
  1387.         movea.l    _topfrac(a4),a3    ; a3 = topfrac
  1388.         movea.l    _bottomfrac(a4),a5 ; a5 = bottomfrac
  1389.         movea.l    _rw_scale(a4),a6 ; a6 = rw_scale
  1390.         bra.w    1$        ; for ( ; rw_x < rw_stopx ; rw_x++)
  1391.  
  1392. 20$        move.l    a2,d0        ; d0 = rw_x
  1393.         move.l    a3,d7        ; d7 = topfrac
  1394.         lea    _ceilingclip(a4),a0 ; a0 -> ceilingclip
  1395.         subq.l    #1,d7        ; d7 = topfrac - 1
  1396.         move.w    (a0,d0.l*2),d3    ; d3.w = ceilingclip[rw_x]
  1397.         asr.l    #8,d7        ; d7 = (topfrac - 1) >> 8
  1398.         ext.l    d3        ; d3 = ceilingclip[rw_x]
  1399.         asr.l    #4,d7        ; d7 = (topfrac - 1) >> 12
  1400.         addq.l    #1,d3        ; d3 = top = ceilingclip[rw_x] + 1
  1401.         addq.l    #1,d7        ; d7 = yl = (topfrac + (1 << 12) - 1) >> 12
  1402.         cmp.l    d3,d7
  1403.         bge    2$
  1404.         move.l    d3,d7        ; d7 = yl = ceilingclip[rw_x] + 1
  1405.  
  1406. 2$        tst.l    _markceiling(a4) ; if (markceiling) {
  1407.         beq.b    3$
  1408.         lea    _floorclip(a4),a1 ; a1 -> floorclip
  1409.         move.l    d7,d4        ; d4 = yl
  1410.         move.w    (a1,d0.l*2),d1    ; d1.w = floorclip[rw_x]
  1411.         subq.l    #1,d4        ; d4 = bottom = yl - 1
  1412.         ext.l    d1        ; d1 = floorclip[rw_x]
  1413.         cmp.l    d1,d4        ; if (bottom >= floorclip[rw_x])
  1414.         blt.b    4$
  1415.         move.l    d1,d4
  1416.         subq.l    #1,d4        ; d4 = bottom = floorclip[rw_x] - 1
  1417.  
  1418. 4$        cmp.l    d4,d3        ; if (top <= bottom)
  1419.         bgt.b    3$
  1420.         movea.l    _ceilingplane(a4),a1
  1421.         adda.l    d0,a1        ; a1 -> ceilingplane->0[rw_x]
  1422.         move.b    d3,$15(a1)    ; ceilingplane->top[rw_x] = top
  1423.         move.b    d4,$157(a1)    ; ceilingplane->bottom[rw_x] = bottom
  1424. 3$        move.l    a5,d3        ; d3 = bottomfrac
  1425.         lea    _floorclip(a4),a1    ; a1 -> floorclip
  1426.         asr.l    #8,d3        ; d3 = bottomfrac >> 8
  1427.         move.w    (a1,d0.l*2),d1    ; d1.w = floorclip[rw_x]
  1428.         asr.l    #4,d3        ; d3 = yh = bottomfrac >> 12
  1429.         ext.l    d1        ; d1 = floorclip[rw_x]
  1430.         cmp.l    d1,d3        ; if (yh >= floorclip[rw_x])
  1431.         blt.b    5$
  1432.         move.l    d1,d3
  1433.         subq.l    #1,d3        ; d3 = yh = floorclip[rw_x] - 1
  1434.  
  1435. 5$        tst.l    _markfloor(a4)    ; if (markfloor)
  1436.         beq.b    6$
  1437.         move.l    d3,d4        ; d4 = yh
  1438.         move.w    (a0,d0.l*2),d2    ; d2.w = ceilingclip[rw_x]
  1439.         addq.l    #1,d4        ; d4 = top = yh + 1
  1440.         ext.l    d2        ; d2 = ceilingclip[rw_x]
  1441.         subq.l    #1,d1        ; d1 = bottom = floorclip[rw_x] - 1
  1442.         cmp.l    d2,d4        ; if (top <= ceilingclip[rw_x])
  1443.         bgt.b    7$
  1444.         move.l    d2,d4
  1445.         addq.l    #1,d4        ; d4 = top = ceilingclip[rw_x] + 1
  1446. 7$        cmp.l    d1,d4        ; if (top <= bottom)
  1447.         bgt.b    6$
  1448.         movea.l    _floorplane(a4),a1
  1449.         adda.l    d0,a1        ; a1 -> floorplane->0[rw_x]
  1450.         move.b    d4,$15(a1)    ; floorplane->top[rw_x] = top
  1451.         move.b    d1,$157(a1)    ; floorplane->bottom[rw_x] = bottom
  1452.  
  1453. 6$        tst.l    _segtextured(a4) ; if (segtextured)
  1454.         beq.b    8$
  1455.         lea    _xtoviewangle(a4),a0 ; a0 -> xtoviewangle
  1456.         move.l    _rw_centerangle(a4),d1
  1457.         add.l    (a0,d0.l*4),d1    ; d1 = rw_centerangle + xtoviewangle[rw_x]
  1458.         swap    d1        ; d1 = angle
  1459.         lea    (_finetangent),a0 ; a0 -> finetangent
  1460.         lsr.w    #3,d1
  1461.         move.l    (a0,d1.w*4),d0    ; d0 = finetangent[angle]
  1462.         movea.l    _FixedMul(a4),a0
  1463.         move.l    _rw_distance(a4),d1
  1464.         jsr    (a0)        ; d0 = FixedMul(finetangent[angle],rw_distance)
  1465.         move.l    _rw_offset(a4),d5
  1466.         move.l    a6,d4        ; d4 = rw_scale
  1467.         sub.l    d0,d5        ; d5 = rw_offset-FixedMul(finetangent[angle],rw_distance)
  1468.         asr.l    #8,d4
  1469.         swap    d5        ; d5.w = texturecolumn >>= 16
  1470.         asr.l    #4,d4        ; d4 = index = rw_scale >> 12
  1471.         ext.l    d5        ; d5 = texturecolumn
  1472.         moveq    #$30,d2        ; d2 = MAXLIGHTSCALE = $30
  1473.         cmp.l    d2,d4        ; if (index >= MAXLIGHTSCALE)
  1474.         bcs.b    9$
  1475.         moveq    #$2f,d4        ; d4 = index = MAXLIGHTSCALE - 1
  1476. 9$        movea.l    _walllights(a4),a0
  1477.         moveq    #-1,d0        ; d0 = $ffffffff
  1478.         move.l    (a0,d4.l*4),_dc_colormap(a4) ; dc_colormap = walllights[index]
  1479.         move.l    a2,_dc_x(a4)    ; dc_x = rw_x
  1480.         move.l    a6,d1        ; d1 = rw_scale
  1481.         divu.l    d1,d0
  1482.         move.l    d0,_dc_iscale(a4) ; dc_iscale = $ffffffff / rw_scale
  1483.  
  1484. 8$        move.l    _midtexture(a4),d0 ; if (midtexture)
  1485.         beq.b    10$
  1486.         move.l    d7,_dc_yl(a4)    ; dc_yl = yl
  1487.         move.l    d3,_dc_yh(a4)    ; dc_yh = yh
  1488.         move.l    _rw_midtexturemid(a4),_dc_texturemid(a4)
  1489.         move.l    d5,d1        ; d1 = texturecolumn
  1490.         jsr    (@R_GetColumn)
  1491.         move.l    d0,_dc_source(a4) ; dc_source = R_GetColumn(midtexture,texturecolumn)
  1492.         movea.l    _colfunc(a4),a0
  1493.         jsr    (a0)        ; colfunc()
  1494.         move.l    a2,d0        ; d0 = rw_x
  1495.         move.l    _viewheight(a4),d1 ; d1 = viewheight
  1496.         lea    _ceilingclip(a4),a0
  1497.         move.w    d1,(a0,d0.l*2)    ; ceilingclip[rw_x] = viewheight
  1498.         lea    _floorclip(a4),a0
  1499.         move.w    #$ffff,(a0,d0.l*2) ; floorclip[rw_x] = -1
  1500.         bra.w    11$
  1501.  
  1502. 10$        move.l    _toptexture(a4),d0 ; if (toptexture)
  1503.         beq.b    12$
  1504.         move.l    _pixhighstep(a4),d1 ; d1 = pixhighstep
  1505.         move.l    _pixhigh(a4),d2    ; d2 = pixhigh
  1506.         add.l    d1,_pixhigh(a4)    ; pixhigh += pixhighstep
  1507.         lea    _floorclip(a4),a0 ; a0 -> floorclip
  1508.         asr.l    #8,d2        ; d2 = pixhigh >> 8
  1509.         move.l    a2,d1        ; d1 = rw_x
  1510.         move.w    (a0,d1.l*2),d1    ; d1.w = floorclip[rw_x]
  1511.         asr.l    #4,d2        ; d2 = pixhigh >> 12
  1512.         ext.l    d1        ; d1 = floorclip[rw_x]
  1513.         move.l    d2,d6        ; d6 = mid = pixhigh >> 12
  1514.         cmp.l    d1,d6        ; if (mid >= floorclip[rw_x])
  1515.         blt.b    13$
  1516.         move.l    d1,d6
  1517.         subq.l    #1,d6        ; d6 = mid = floorclip[rw_x] - 1
  1518. 13$        cmp.l    d7,d6        ; if (mid >= yl)
  1519.         blt.b    14$
  1520.         move.l    d7,_dc_yl(a4)    ; dc_yl = yl
  1521.         move.l    d6,_dc_yh(a4)    ; dc_yh = mid
  1522.         move.l    _rw_toptexturemid(a4),_dc_texturemid(a4)
  1523.         move.l    d5,d1        ; d1 = texturecolumn, d0 = toptexture
  1524.         jsr    (@R_GetColumn)
  1525.         move.l    d0,_dc_source(a4)    ; dc_source = R_GetColumn(d0,d1)
  1526.         movea.l    _colfunc(a4),a0
  1527.         jsr    (a0)        ; colfunc()
  1528.         move.l    a2,d0        ; d0 = rw_x
  1529.         lea    _ceilingclip(a4),a0
  1530.         move.w    d6,(a0,d0.l*2)    ; ceilingclip[rw_x] = mid
  1531.         bra.b    15$
  1532.  
  1533. 12$        tst.l    _markceiling(a4) ; else if (markceiling)
  1534.         beq.b    15$
  1535. 14$        subq.l    #1,d7        ; d7 = yl - 1
  1536.         move.l    a2,d0        ; d0 = rw_x
  1537.         lea    _ceilingclip(a4),a0
  1538.         move.w    d7,(a0,d0.l*2)    ; ceilingclip[rw_x] = yl - 1
  1539.  
  1540. 15$        move.l    _bottomtexture(a4),d0 ; if (bottomtexture)
  1541.         beq.b    16$
  1542.         move.l    _pixlow(a4),d6    ; d6 = pixlow
  1543.         move.l    d6,d1        ; d1 = pixlow
  1544.         lea    _ceilingclip(a4),a0 ; a0 -> ceilingclip
  1545.         add.l    _pixlowstep(a4),d1 ; d1 = pixlow + pixlowstep
  1546.         subq.l    #1,d6        ; d6 = pixlow - 1
  1547.         move.l    d1,_pixlow(a4)    ; pixlow += pixlowstep
  1548.         asr.l    #8,d6        ; d6 = (pixlow - 1) >> 8
  1549.         move.l    a2,d1        ; d1 = rw_x
  1550.         asr.l    #4,d6        ; d6 = (pixlow - 1) >> 12
  1551.         move.w    (a0,d1.l*2),d1    ; d1.w = ceilingclip[rw_x]
  1552.         addq.l    #1,d6        ; d6 = mid = (pixlow + (1 << 12) - 1) >> 12
  1553.         ext.l    d1        ; d1 = ceilingclip[rw_x]
  1554.         cmp.l    d1,d6        ; if (mid <= ceilingclip[rw_x])
  1555.         bgt.b    17$
  1556.         move.l    d1,d6
  1557.         addq.l    #1,d6        ; d6 = mid = ceilingclip[rw_x] + 1
  1558. 17$        cmp.l    d3,d6        ; if (mid <= yh)
  1559.         bgt.b    18$
  1560.         move.l    d6,_dc_yl(a4)    ; dc_yl = mid
  1561.         move.l    d3,_dc_yh(a4)    ; dc_yh = yh
  1562.         move.l    _rw_bottomtexturemid(a4),_dc_texturemid(a4)
  1563.         move.l    d5,d1        ; d1 = texturecolumn, d0 = bottomtexture
  1564.         jsr    (@R_GetColumn)
  1565.         move.l    d0,_dc_source(a4) ; dc_source = R_GetColumn(d0,d1)
  1566.         movea.l    _colfunc(a4),a0
  1567.         jsr    (a0)        ; colfunc ()
  1568.         move.l    a2,d0        ; d0 = rw_x
  1569.         lea    _floorclip(a4),a0
  1570.         move.w    d6,(a0,d0.l*2)    ; floorclip[rw_x] = mid
  1571.         bra.b    19$
  1572.  
  1573. 16$        tst.l    _markfloor(a4)    ; else if (markfloor)
  1574.         beq.b    19$
  1575. 18$        addq.l    #1,d3        ; d3 = yh + 1
  1576.         move.l    a2,d0        ; d0 = rw_x
  1577.         lea    _floorclip(a4),a0
  1578.         move.w    d3,(a0,d0.l*2)    ; floorclip[rw_x] = yh + 1
  1579.  
  1580. 19$        tst.l    _maskedtexture(a4) ; if (maskedtexture)
  1581.         beq.b    11$
  1582.         move.l    a2,d0        ; d0 = rw_x
  1583.         movea.l    _maskedtexturecol(a4),a0
  1584.         move.w    d5,(a0,d0.l*2)    ; maskedtexturecol[rw_x] = texturecolumn
  1585.  
  1586. 11$        adda.l    _rw_scalestep(a4),a6 ; rw_scale += rw_scalestep
  1587.         adda.l    _topstep(a4),a3    ; topfrac += topstep
  1588.         adda.l    _bottomstep(a4),a5 ; bottomfrac += bottomstep
  1589.         addq.l    #1,a2        ; rw_x++
  1590.  
  1591. 1$        cmpa.l    _rw_stopx(a4),a2
  1592.         blt.w    20$
  1593.  
  1594.         move.l    a2,_rw_x(a4)
  1595.         move.l    a3,_topfrac(a4)
  1596.         move.l    a5,_bottomfrac(a4)
  1597.         move.l    a6,_rw_scale(a4)
  1598.  
  1599.         movem.l    (sp)+,d2-d7/a2-a6
  1600.         rts
  1601.  
  1602. ;***********************************************************************
  1603.  
  1604.         end
  1605.